#include "stm8s_uart1.h"
#include "stm8s_gpio.h"
#include "stm8s_clk.h"
#include <string.h>
#include "sys_pub.h"

#include "uart_comm_def.h"

static uart_protocol_typeDef uart_protocol;

// 外部声明10ms系统Tick(用户需确保该变量每10ms递增)

/**
 * @brief  初始化UART1硬件
 * @param  baud_rate: 波特率
 * @retval None
 */
void uart1_hw_init(uint32_t baud_rate, parse_enter_func parse_func)
{
    // 初始化缓冲区
    memset(&uart_protocol, 0, sizeof(uart_protocol_typeDef));
    uart_protocol.rx_buf.last_rx_tick = TICK_INVALID;
    uart_protocol.parse_func = parse_func;
    // 使能UART1时钟
    CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART1, ENABLE);

    // 配置UART1参数(8位数据，1位停止位，无校验，收发使能)
    UART1_Init(baud_rate,
               UART1_WORDLENGTH_8D,
               UART1_STOPBITS_1,
               UART1_PARITY_NO,
               UART1_SYNCMODE_CLOCK_DISABLE,
               UART1_MODE_TXRX_ENABLE);

    // 使能接收中断(RXNE和OR中断)
    UART1_ITConfig(UART1_IT_RXNE_OR, ENABLE);

    // 使能UART1
    UART1_Cmd(ENABLE);

    // 使能全局中断
    enableInterrupts();
}

/**
 * @brief  清除接收缓冲区
 * @retval None
 */
void uart1_clear_rx_buffer(void)
{
    uart_protocol.rx_buf.len = 0;
    uart_protocol.rx_buf.overflow = 0;
    uart_protocol.rx_buf.last_rx_tick = TICK_INVALID;
    memset(uart_protocol.rx_buf.buffer, 0, MAX_RX_BUF_LEN);
}

/**
 * @brief  检查是否接收完一帧数据
 * @note   通过判断当前10ms Tick与最后接收Tick的差值是否超过超时阈值
 * @retval 1: 帧已完成, 0: 未完成
 */
uint8_t uart1_is_frame_complete(void)
{
    // 没有接收任何数据, 不算完成
    if (uart_protocol.rx_buf.len == 0 ||
        uart_protocol.rx_buf.last_rx_tick == TICK_INVALID)
    {
        return 0;
    }

    // 计算10ms级时间差(处理Tick溢出)
    uint32_t current_tick = sys_get_tick_ms();
    uint16_t diff;

    if (current_tick >= uart_protocol.rx_buf.last_rx_tick)
    {
        diff = current_tick - uart_protocol.rx_buf.last_rx_tick;
    }
    else
    {
        // 处理16位Tick溢出(0xFFFF -> 0x0000)
        diff = (0xFFFF - uart_protocol.rx_buf.last_rx_tick) + current_tick + 1;
    }

    return (diff >= FRAME_TIMEOUT_MS) ? 1 : 0;
}

/**
 * @brief  协议处理主函数
 * @retval 处理结果
 */
protocol_result_typeDef uart1_protocol_process(void)
{
    protocol_result_typeDef result = PROTOCOL_RESULT_UNKNOWN;
    uint16_t tx_len = 0;
    uint8_t tx_data[MAX_RX_BUF_LEN];

    // 检查缓冲区溢出
    if (uart_protocol.rx_buf.overflow)
    {
        uart1_clear_rx_buffer();
        return PROTOCOL_RESULT_ERROR;
    }

    // 检查帧是否完成
    if (!(uart1_is_frame_complete() && uart_protocol.rx_buf.len > 0))
    {
        return result;
    }
    // 调用解析函数(用户需实现具体协议解析)
    if (uart_protocol.parse_func != NULL)
    {
        result = uart_protocol.parse_func(uart_protocol.rx_buf.buffer, uart_protocol.rx_buf.len, tx_data, &tx_len);
    }
    // 检查帧是否完成

    // 根据解析结果处理
    switch (result)
    {
    case PROTOCOL_RESULT_OK:
        // 发送响应
        if (tx_len > 0)
        {
            for (uint16_t i = 0; i < tx_len; i++)
            {
                while (UART1_GetFlagStatus(UART1_FLAG_TXE) == RESET)
                    ;
                UART1_SendData8(tx_data[i]);
            }
            while (UART1_GetFlagStatus(UART1_FLAG_TC) == RESET)
                ;
        }
        // 清除缓冲区准备下一帧
        uart1_clear_rx_buffer();
        break;

    default:
        // 解析错误或不完整, 清除缓冲区
        uart1_clear_rx_buffer();
        break;
    }

    return result;
}

/**
 * @brief  UART1中断服务程序
 * @retval None
 */
INTERRUPT_HANDLER(UART1_IRQHandler, 18)
{
    uint8_t rx_data;

    // 接收数据可用中断
    if (UART1_GetITStatus(UART1_IT_RXNE) == SET)
    {
        // 读取接收数据
        rx_data = UART1_ReceiveData8();

        // 检查缓冲区溢出
        if (uart_protocol.rx_buf.len < MAX_RX_BUF_LEN)
        {
            uart_protocol.rx_buf.buffer[uart_protocol.rx_buf.len++] = rx_data;
            uart_protocol.rx_buf.last_rx_tick = sys_get_tick_ms(); // 更新最后接收时间(10ms级)
        }
        else
        {
            uart_protocol.rx_buf.overflow = 1;
        }

        // 清除中断标志
        UART1_ClearITPendingBit(UART1_IT_RXNE);
    }

    // 溢出错误处理
    if (UART1_GetITStatus(UART1_IT_OR) == SET)
    {
        uart_protocol.rx_buf.overflow = 1;
        UART1_ClearITPendingBit(UART1_IT_OR);
    }
}

